package net.goutalk.glcs.module.workflow.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import net.goutalk.glcs.common.constant.GlobalConstant;
import net.goutalk.glcs.common.page.ConventPage;
import net.goutalk.glcs.common.page.PageOutput;
import net.goutalk.glcs.common.utils.RedisUtil;
import net.goutalk.glcs.module.organization.entity.User;
import net.goutalk.glcs.module.workflow.dto.AddDelegateDto;
import net.goutalk.glcs.module.workflow.dto.DelegatePageDto;
import net.goutalk.glcs.module.workflow.dto.UpdateDelegateDto;
import net.goutalk.glcs.module.workflow.entity.WorkflowDelegate;
import net.goutalk.glcs.module.workflow.mapper.WorkflowDelegateMapper;
import net.goutalk.glcs.module.workflow.service.IWorkflowDelegateService;
import net.goutalk.glcs.module.workflow.vo.DelegatePageVo;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 流程委托 服务实现类
 * </p>
 *
 * @author tanyujie
 * @since 2022-11-05
 */
@Service
@AllArgsConstructor
public class WorkflowDelegateServiceImpl extends ServiceImpl<WorkflowDelegateMapper, WorkflowDelegate> implements IWorkflowDelegateService {

    private final RedisUtil redisUtil;
    @Override
    public PageOutput<DelegatePageVo> page(DelegatePageDto dto) {
        //用户只能看到自己的流程委托信息
        LambdaQueryWrapper<WorkflowDelegate> eq = Wrappers.lambdaQuery(WorkflowDelegate.class)
                .eq(WorkflowDelegate::getUserId,StpUtil.getLoginIdAsLong())
                .like(StrUtil.isNotBlank(dto.getKeyword()), WorkflowDelegate::getRemark, dto.getKeyword())
                .or(StrUtil.isNotBlank(dto.getKeyword()))
                .like(StrUtil.isNotBlank(dto.getKeyword()), WorkflowDelegate::getDelegateUserNames, dto.getKeyword());
        IPage<WorkflowDelegate> page = page(ConventPage.getPage(dto), eq);

        PageOutput<DelegatePageVo> pageOutput = ConventPage.getPageOutput(page, DelegatePageVo.class);

        User user = StpUtil.getTokenSession().get(GlobalConstant.LOGIN_USER_INFO_KEY, new User());

        for (DelegatePageVo delegatePageVo : pageOutput.getList()) {
            delegatePageVo.setDelegator(user.getName());

        }

        return pageOutput;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean add(AddDelegateDto dto) {

        WorkflowDelegate delegate = BeanUtil.toBean(dto, WorkflowDelegate.class);
        delegate.setUserId(StpUtil.getLoginIdAsLong());

        List<User> allUser = redisUtil.get(GlobalConstant.USER_CACHE_KEY, new TypeReference<List<User>>() {
        });
        String allUserIdStr = StrUtil.join(StringPool.COMMA, dto.getDelegateUserIds());
        List<Long> ids = Arrays.stream(allUserIdStr.split(StringPool.COMMA)).map(Convert::toLong).collect(Collectors.toList());
        List<String> names = allUser.stream().filter(x -> ids.contains(x.getId())).map(User::getName).collect(Collectors.toList());
        delegate.setDelegateUserNames(StrUtil.join(StringPool.COMMA,names));

        return save(delegate);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(UpdateDelegateDto dto) {

        WorkflowDelegate delegate = BeanUtil.toBean(dto, WorkflowDelegate.class);
        delegate.setUserId(StpUtil.getLoginIdAsLong());

        List<User> allUser = redisUtil.get(GlobalConstant.USER_CACHE_KEY, new TypeReference<List<User>>() {
        });
        String allUserIdStr = StrUtil.join(StringPool.COMMA, dto.getDelegateUserIds());
        List<Long> ids = Arrays.stream(allUserIdStr.split(StringPool.COMMA)).map(Convert::toLong).collect(Collectors.toList());
        List<String> names = allUser.stream().filter(x -> ids.contains(x.getId())).map(User::getName).collect(Collectors.toList());
        delegate.setDelegateUserNames(StrUtil.join(StringPool.COMMA,names));

        return updateById(delegate);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(List<Long> ids){

        return removeBatchByIds(ids);
    }
}
